#pragma once

#include "Business/IDealingHandler.h"

class Dealing;
class Trade;

class PositionKey
{
public:
	PositionKey(int contract, int direction,int offsetOperation)
	:m_contract(contract),m_direction(direction),m_offsetOperation(offsetOperation)
	{
	}
	int GetContract() const { return m_contract; }
	int GetDirection() const { return m_direction; }
	int GetOffsetOperation() const { return m_offsetOperation; }

	bool operator<(PositionKey const& other) const
	{
		if (m_contract < other.m_contract)
			return true;
		else if (m_contract == other.m_contract)
		{
			if (m_direction < other.m_direction)
				return true;
			else if (m_direction == other.m_direction)
				return m_offsetOperation < other.m_offsetOperation;
		}
		return false;
	}
private:
	int m_contract;
	int m_direction;
	int m_offsetOperation;
};

class PositionValue
{
public:
	PositionValue()
	:m_price(0.00),m_quantity(0)
	{
	}
	PositionValue(double price,int quantity)
	:m_price(price),m_quantity(quantity)
	{
	}
	double GetPrice() const { return m_price; }
	int GetQuantity() const { return m_quantity; }
	int GetAvailable() const { return m_quantity - m_freezeQuantity;}
	double GetTotal() const { return m_quantity * m_price; }

	PositionValue& Plus(PositionValue const& other);
	PositionValue& Sub(PositionValue const& other);

	PositionValue& Sub(int quantity);
private:
	double m_price;
	int m_quantity;
	int m_available;
	int m_freezeQuantity;
};

class CustomerPosition : public IDealingHandler
{
public:
	CustomerPosition(){}
	virtual ~CustomerPosition() {}
	void Plus(PositionKey const& key, PositionValue const& value);
	PositionValue const& Get(PositionKey const& key) const;
	PositionValue const& Get(Dealing const& dealing) const;

private:
	Operation::TYPE GetOperation(Dealing const& dealing) const;
	Direction::TYPE GetDirection(Dealing const& dealing) const;
	
	virtual void DoOnDealing(Dealing const& dealing);
	virtual void DoOnTrade(Trade const& trade);

	std::map<PositionKey,PositionValue> m_positions;
};